--[[

将lua面向对象化

base_type = Class()

function base_type:Ctor(x)
	print("base_type ctor")
	self.x = x
end

function base_type:print_x()
	print(self.x)
end

function base_type:hello()
	print("hello base_type")
end

test = Class(base_type)

function test:Ctor()
	print("test ctor")
end

function test:hello()
	print("hello test")
end

a = test(1)
a:print_x()
a:hello()

--]]

local Class_Create
Class_Create = function(c, o, ...)
	-- 检查是否有父类模版，如果有则调用父类的构造函数。
	if c.__parent then Class_Create(c.__parent, o, ...) end
	-- 如果当前类有定义Ctor函数，则调用。
	if c.Ctor then c.Ctor(o, ...) end
end

-- 记录所有的类模版
ALL_CLASS = {}

-- 定义类
function Class(parent)
	-- 检查父类是否存在，不存在则报错
	if parent then assert(ALL_CLASS[parent]) end
	-- 定义类模版
	local class_type = {}
	-- 定义类模版的元表
	local mt = {}
	-- 设置类模版的元表
	setmetatable(class_type, mt)
	-- 设置类模版的父类模版
	class_type.__parent = parent
	-- 设置元表的索引为父类模版。这样当使用类模版不存在的函数和属性时会到父类模版中查找
	mt.__index = parent
	-- 设置call函数。这样创建类实例对象时，可以使用a = A()这样的书写方式。“...”表示不定长参数列表
	mt.__call = function (caller, ...)
		-- 创建类实例对象
		local object = {}
		-- 创建实例对象的元表
		local object_mt = {}
		-- 设置实例对象的元表
		setmetatable(object, object_mt)
		-- 设置实例对象元表的索引为当前类模版
		object_mt.__index = class_type
		-- 向父类模版递归调用Ctor函数。这里模拟C++的构造函数。
		Class_Create(class_type, object, ...)
		-- 返回创建的实例对象
		return object
	end

	-- 保存类定义
	ALL_CLASS[class_type] = class_type
	-- 返回类模版
	return class_type
end
